<template>
  <div class="home">
    <div class="header">
      <van-icon class="return" name="arrow-left" @click="goChannel" />
      <img class="bg-img" src="@/assets/img/title_bg.png" />
      <div class="title">
        <img src="@/assets/img/titlebigtou_img.png" />
      </div>
      <help />
    </div>

    <div class="main-box">
      <div class="form">
        <van-form ref="formRef" @submit="onSubmit" @failed="onFailed">
          <section class="mb-10 form-box">
            <van-field
              @click="onSelectAddress"
              v-model="state.orderData.address"
              required
              readonly
              type="textarea"
              rows="1"
              autosize
              name="address"
              label="所在地区"
              placeholder="请选择定位"
              :rules="[{ required: true, message: '请选择定位' }]"
            >
              <template #right-icon>
                <span class="address-right">
                  <van-icon class="address-icon" name="location" />
                  定位
                </span>
              </template>
            </van-field>
            <van-field
              required
              name="addressDetail"
              v-model="state.orderData.addressDetail"
              label="门牌号"
              placeholder="门牌号，1号楼2层201室"
              type="textarea"
              rows="1"
              autosize
              :rules="[{ required: true, message: '请填写门牌号' }]"
            />
            <van-field
              name="isDance"
              label="小熊猫跳舞"
              placeholder="根据所选地区确定是否跳舞"
              readonly>
              <template #input>
                {{ state.orderData.isDance === true ? '有跳舞服务' : state.orderData.isDance === false ? '无跳舞服务' : '-' }}
              </template>
            </van-field>
            <van-field
              required
              name="deliveryName"
              v-model="state.orderData.deliveryName"
              label="收货人"
              placeholder="请输入收货人姓名"
              :rules="[{ required: true, message: '请输入收货人姓名' }]"
            />
            <van-field
              required
              name="receiverPhone"
              v-model="state.orderData.receiverPhone"
              label="收货人电话"
              placeholder="请输入收货人手机号"
              :rules="[{ required: true, message: '请输入收货人手机号' }]"
              :formatter="phoneFormatter"
              format-trigger="onChange"
              @update:model-value="onRecPhoneChange"
            />
            <van-checkbox class="ml-15 mt-5" v-model="state.isSameReceiver" shape="square" checked-color="#ee0a24" icon-size="16px" @change="onSamePhoneChange">
              <span class="fz-14">同收货人</span>
            </van-checkbox>
            <van-field
              required
              name="bookerPhone"
              v-model="state.orderData.bookerPhone"
              label="下单人电话"
              placeholder="请输入下单人手机号"
              :disabled="state.isSameReceiver"
              :formatter="phoneFormatter"
              format-trigger="onChange"
              :rules="[{ required: true, message: '请输入下单人手机号' }]"
            />
            <van-field
              name="deliveryDate"
              label="收货时间"
              placeholder="请选择收货时间"
              required
              readonly
              is-link
              clearable
              @click="onDateClick"
            >
              <template #input>
                <span v-if="state.orderData.deliveryDate && state.orderData.deliveryTimeSlot">
                  {{ `${state.orderData.deliveryDate || ''} ${getSpliceTimeText(state.orderData.deliveryTimeSlot) || ''}` }}
                </span>
                <span v-else class="c-c8c9cc">
                  请选择收货时间
                </span>
              </template>
            </van-field>
          </section>

          <section class="form-box mb-10">
            <van-field
              class="blessings"
              name="blessings"
              v-model="state.orderData.blessings"
              type="textarea"
              rows="1"
              autosize
              label="祝福语"
              maxlength="30"
              placeholder="默认祝福语：祝你生日快乐！"
              :show-word-limit="!!(state.orderData.blessings && state.orderData.blessings.length === 30)"
            />

            <van-field
              name="remark"
              v-model="state.orderData.remark"
              type="textarea"
              rows="1"
              autosize
              maxlength="50"
              label="其他备注"
              placeholder="请填写其他备注"
              :show-word-limit="!!(state.orderData.remark && state.orderData.remark.length === 50)"
            />
          </section>

          <section class="upload-box mb-20">
            <div class="upload-code-title">
              <span class="fz-14">上传券码</span>
              <span class="code fz-14">{{
                state.orderData.couponCode
                  ? state.orderData.couponCode.replace(/(\w{4})(?=\w)/g, "$1 ")
                  : "自动识别券码"
              }}</span>
              <guide ref="guideRef" />
            </div>

            <div class="upload mt-10">
              <van-uploader
                ref="upload"
                name="uploader"
                :before-read="beforeRead"
              >
                <div class="upload-bg" :style="{backgroundImage:`url(${images.uploadBgImg})`}">
                  <img
                    v-if="state.orderData.codeUrl"
                    :src="state.orderData.codeUrl"
                    class="upload-img"
                  />
                  <img
                    v-if="state.orderData.codeUrl"
                    class="view"
                    src="@/assets/img/icon-view.png"
                    alt=""
                    @click.stop="onPreview"
                  />
                </div>
                <div class="c-999 mt-5 fz-12">点击上传团购券</div>
              </van-uploader>
            </div>

            <div v-if="state.isDecodeError">
              <div class="fz-12 c-999 ml-10">解析券码失败？尝试手动输入券码</div>
              <van-field
                required
                class="pd-0"
                name="couponCode"
                v-model="state.orderData.couponCode"
                label="券码"
                placeholder="请输入券码">
                <template #button>
                  <van-button size="mini" type="danger" @click="handleCompleteCode">完成输入</van-button>
                </template>
              </van-field>
            </div>

            <div class="line" v-if="state.goodsList && state.goodsList.length">
              <span class="circle left"></span>
              <span class="circle right"></span>
            </div>

            <div
              class="goods-list"
              v-if="state.goodsList && state.goodsList.length"
            >
              <span class="circle left"></span>
              <div
                :class="{ checked: item.skuId === state.selectedGoods.skuId }"
                class="goods-item"
                v-for="(item, index) in state.goodsList"
                :key="index"
                @click="onSelectGoods(item)"
              >
                <div v-if="item.soldOut" class="sold-out">
                  <span>已售罄</span>
                </div>
                <img class="goods-img" :src="item.imageUrl" />
                <div class="pd-5">
                  <div class="fz-12 mb-5 c-333">{{ item.marketName }}</div>
                  <img v-if="item.soldOut" class="circle-icon" src="@/assets/img/radio.svg" />
                  <van-icon
                    class="c-ff3102 fz-16"
                    name="checked"
                    v-else-if="item.skuId === state.selectedGoods.skuId"
                  />
                  <van-icon v-else name="circle fz-16" />
                </div>
              </div>
            </div>
          </section>
          <div>
            <van-button round block type="danger" native-type="submit">
              提交
            </van-button>
          </div>
        </van-form>
      </div>
      <!-- <div class="ta-c ptb-15">客服微信：{{appConfig.wechat}}</div> -->
      <div class="ta-c ptb-15 c-999 fz-14">
        <span class="mr-20 d-if-ac" @click="onContact">
          <van-icon name="service-o" class="fz-16 mr-5" />
          联系客服
        </span>
        <span class="d-if-ac">
          <van-icon name="phone-o" class="fz-16 mr-5" />
          <a href="tel:02180394682">02180394682</a>
        </span>
      </div>
    </div>

    <Loading v-if="state.loading">{{ state.loadingText }}</Loading>
    
    <van-dialog
      v-model:show="state.showSubmitTip"
      title=""
      @confirm="submitConfirm"
      :confirm-button-text="'我知道了'"
    >
      <div class="submit-tip">
        <p>1. 商家确认订单无误后有短信通知（预计30-60分钟）</p>
        <p>2. 蛋糕均有配置烟花蜡烛、生日帽、餐具（下午茶只有餐具）</p>
        <p>3. 每个订单均有小熊猫免费送货上门并跳舞</p>
        <p>4. 配送1小时区间，配送前30-60分钟会有电话联系</p>
        <p>如有其他疑问，可加微信: {{ appConfig.wechat }}</p>
      </div>
    </van-dialog>
    <timeSelector ref="timeSelectorRef" @confirm="onDateConfirm" :addressObj="state.addressObj" :orderData="state.orderData" :needBeforeThreeDay="needBeforeThreeDay" />
    <statementDialog />
  </div>
</template>

<script>
import { defineComponent, reactive, ref, watch, nextTick, computed, onActivated } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ImagePreview, Toast, Notify, Dialog } from "vant";
import { Getupload, submitOrder } from "@/api/common";
import { getBase64, decodeQrCode, changeHttpImageUrl } from "@/utils/image";
import { isMobile, onContact } from "@/utils";
import { getSpliceTimeText } from "@/utils/time";
import { setPhoneTokenMap } from '@/utils/storage'
import { getGoodsByGroupCode, getIsDance } from "@/api/home/index.js";
import guide from "./components/guide";
import help from "./components/help";
import timeSelector from "./components/timeSelector";
import store from "@/store";
import Loading from '@/components/Loading'
import { triggerTipDialog } from '@/composition/errorTipDialogConfig'
import statementDialog from "./components/statementDialog";
const images = {
  uploadBgImg: require('@/assets/img/upload.png')
}
import EventTracking from '@/utils/EventTracking'
import dayjs from "dayjs";
// 修改内容埋点
const editTracking = new EventTracking({
  oneceTime: true,
  enterType: '4'
})
// 上传券码埋点
const uploadTracking = new EventTracking({
  oneceTime: true,
  enterType: '5'
})

const phoneFormatter = (value) => value.replace(/[\s]/g, '');

export default defineComponent({
  name: 'Home',
  components: {
    guide,
    help,
    timeSelector,
    Loading,
    statementDialog,
  },
  setup() {
    const guideRef = ref(null);
    const formRef = ref(null)
    const timeSelectorRef = ref(null)
    const appConfig = computed(() => store.getters.appConfig)
    const needBeforeThreeDay = computed(() => state.selectedGoods && state.selectedGoods.marketName && state.selectedGoods.marketName.includes('提前3天'))
    const state = reactive({
      goodsList: [],
      price: "",
      selectedGoods: {},
      orderData: {},
      currentDate: new Date(),
      minDate: new Date(),
      maxDate: new Date(2025, 12, 1),
      showDate: false,
      showTime: false,
      showSubmitTip: false,
      timeSlot: [],
      timeSlotList: [],
      addressObj: {},
      loadingText: '',
      loading: false,
      isDecodeError: false, // 解析二维码失败
      isSameReceiver: true, // 同收货人号码
    });
    let cityName = "";
    const router = useRouter();
    const route = useRoute();
    const getChannelId = () => {
      let channelId = route.query.channel;
      localStorage.setItem('channelId', channelId)
      return channelId
    }

    const onPreview = () => {
      ImagePreview({
        images: [state.orderData.codeUrl],
        closeable: true,
        "class-name": "home-code-image-preview",
      });
    };

    const onDateClick = () => {
      if (!state.orderData.address) {
        Toast.fail("请先选择定位");
        return;
      }
      timeSelectorRef.value.show()
    }
    const onDateConfirm = ({date, time}) => {
      state.orderData.deliveryDate = date
      state.orderData.deliveryTimeSlot = time
    }
    const beforeRead = (file) => {
      if (!state.orderData.address || !state.orderData.addressDetail) {
        Toast.fail({
          message: "请先选址所在地区和填写门牌号",
          duration: 2000,
        });
        return false;
      }
      if (!cityName) {
        Toast.fail({
          message: "城市名为空，请重新定位选择城市与地址",
          duration: 2000,
        });
        return false;
      }
      handleUpload(file);
    };
    const handleLoading = (status, text) => {
      state.loading = status
      state.loadingText = text || '请稍等...'
    }
    const handleUpload = async (data) => {
      try {
        handleLoading(true, '获取蛋糕商品中，请稍等...')
        clearGoodsInfo()
        if (data.type !== "image/jpeg" && data.type !== "image/png") {
          throw new Error('请上传 jpg 格式与png格式的图片')
        } else {
          const base64Image = await getBase64(data)
          const formData = new FormData();
          formData.append("base64", base64Image);
          formData.append("tag", "groupbuy");
          const uploadRes = await Getupload(formData)
          uploadTracking.send()
          if (uploadRes.code == "200" && uploadRes.data) {
            Notify({ type: "success", message: "卡券照片上传成功" });
            state.orderData.codeUrl = changeHttpImageUrl(uploadRes.data);
            const codeRes = await decodeQrCode(base64Image)
            if (codeRes) {
              Notify({ type: "success", message: "券码识别成功" });
              state.orderData.couponCode = codeRes;
              await getGoodsList();
            } else {
              state.isDecodeError = true
              throw new Error('券码识别失败，请保证照片清晰，或尝试手动输入券码')
            }
            handleLoading(false)
          } else {
            throw new Error('卡券照片上传失败，请联系客服')
          }
        }
      } catch (error) {
        handleUploadError(error)
      }
    };

    // 上传券码错误处理
    const handleUploadError = (error) => {
      console.error(error)
      handleLoading(false)
      state.selectedGoods = {}
      state.goodsList = []
      if (error.message !== '系统繁忙') {
        triggerTipDialog({message: error.message || '获取蛋糕商品失败，重试或联系客服！', title: '提示', show: true})
      }
    }

    // 手动输入券码
    const handleCompleteCode = async () => {
      try {
        handleLoading(true, "获取蛋糕商品中，请稍等...")
        await getGoodsList();
        handleLoading(false)
      } catch (error) {
        handleLoading(false)
        triggerTipDialog({message: '获取蛋糕商品失败，重试或联系客服！', title: '提示', show: true})
      }
    }

    const clearGoodsInfo = () => {
      state.selectedGoods = {}
      state.orderData.codeUrl = ''
      state.orderData.couponCode = ''
      state.goodsList = []
    }

    // 获取商品列表
    const getGoodsList = async () => {
      const obj = {
        cityName,
        groupCode: state.orderData.couponCode,
        channelId: getChannelId(),
        storeId: ''
      };
      const res = await getGoodsByGroupCode(obj)
      if (res.code !== 200) {
        state.goodsList = [];
        throw new Error('获取蛋糕商品失败，重试或联系客服！')
      }
      state.price = res.data.price;
      state.goodsList = res.data.goods || [];
      if (state.goodsList.length === 0) {
        throw new Error('获取蛋糕商品失败，重试或联系客服！')
      }
      // const defaultSelected = state.goodsList.find(item => !item.soldOut)
      // defaultSelected && onSelectGoods(defaultSelected);
    };
    const onSelectGoods = (item) => {
      if (item.soldOut) {
        Toast.fail("商品已售罄，请联系客服！");
        return
      }
      state.selectedGoods = item || {};
      handleTimeByGoodsName()
    };
    // 定制款，需要提前3天下单
    const handleTimeByGoodsName = () => {
      if (needBeforeThreeDay.value && state.orderData.deliveryDate && state.orderData.deliveryTimeSlot) {
        const selectDate = dayjs(state.orderData.deliveryDate + ' ' + state.orderData.deliveryTimeSlot.slice(0, 8))
        const afterThreeDayDate = dayjs().add(3, 'day')
        if (selectDate.unix() >= afterThreeDayDate.unix()) {
          return
        }
        state.orderData.deliveryDate = ''
        Dialog.confirm({
          title: '提示',
          message: '主人，该款为定制蛋糕，需要提前3天下单！',
        })
          .then(() => {
            timeSelectorRef.value.show()
          })
          .catch(() => {
            timeSelectorRef.value.show()
          });
      }
    }
    const onSubmit = () => {
      const errorMsg = validateMsg();
      if (errorMsg) {
        Toast.fail(errorMsg);
        return;
      }
      // state.showSubmitTip = true;
      submitConfirm();
    };
    const submitConfirm = () => {
      const params = getParams();
      handleLoading(true, '提交中，请稍等...')
      submitOrder(params).then((res) => {
        if (res.code == 200) {
          const phoneTokenMap = {
            [state.orderData.receiverPhone]: res.data.token,
            [state.orderData.bookerPhone]: res.data.token,
          }
          setPhoneTokenMap(phoneTokenMap)
          router.push({
            path: "/submit_success",
            query: {orderId: res.data.orderId}
          });
        }
      }).finally(() => {
        handleLoading(false)
      });
    };
    const onFailed = ({errors}) => {
      if (errors && errors.length) {
        const err = errors[0]
        Toast.fail(err.message)
        formRef.value.scrollToField(err.name)
      }
    }
    // 校验
    const validateMsg = () => {
      const keyMap = {
        deliveryDate: "请选择配送日期",
        deliveryTimeSlot: "请选择配送时间",
        couponCode: "当前券码为空",
        codeUrl: "请上传券码",
      };
      let errorMsgKey = Object.keys(keyMap).find(
        (key) => !state.orderData[key]
      );
      if (errorMsgKey) {
        return keyMap[errorMsgKey];
      }
      if (!isMobile(state.orderData.receiverPhone)) {
        return "收货人电话号码格式错误";
      }
      if (!isMobile(state.orderData.bookerPhone)) {
        return "下单人电话号码格式错误";
      }
      if (!state.selectedGoods || !state.selectedGoods.skuId) {
        return "请选择需要兑换款式";
      }
    };
    const getParams = () => {
      const params = {
        blessings: state.orderData.blessings || '祝你生日快乐！', //祝福语
        bookerPhone: state.orderData.bookerPhone, //下单电话号
        receiverPhone: state.orderData.receiverPhone, //收货电话号
        consumerRemark: state.orderData.remark, //备注
        receiverName: state.orderData.deliveryName, // 收货人名称
        selfDeliveryId: "", // 自提仓库
        deliveryDate: state.orderData.deliveryDate, // 日期
        deliveryTimeSlot: state.orderData.deliveryTimeSlot, //时间段
        deliveryWay: 2, // 判断 支付宝还是 美团
        latitude: state.orderData.latitude,
        longitude: state.orderData.longitude,
        receiverAddress: state.orderData.address + state.orderData.addressDetail,
        platformOrderId: state.orderData.couponCode, // 券码
        qrCodeUrl: state.orderData.codeUrl, // 团购图片
        channelId: getChannelId(), // 渠道
        price: state.price || '168',
        merchantName: "",// 门店
        merchantId: "",// 门店id
        isDance: state.orderData.isDance,// 跳舞属性
        skuInfos: [
          {
            skuId: state.selectedGoods.skuId,
            iamgeUrl: state.selectedGoods.imageUrl,
            marketName: 1,
          },
        ],
      };
      return params;
    };
    
    const onSelectAddress = () => {
      router.push({
        path: "/map",
        query: route.query,
      });
    };

    const getCacheOrder = () => {
      return new Promise((resolve) => {
        const order = JSON.parse(localStorage.getItem("groupbuy_order_data"));
        if (order) {
          state.orderData = order;
        }
        resolve(order);
      });
    };

    const onRecPhoneChange = (value) => {
      state.orderData.bookerPhone = value
    }

    const onSamePhoneChange = (value) => {
      if (value) {
        state.orderData.bookerPhone = state.orderData.receiverPhone
      }
    }

    const setCacheTimer = () => {
      setInterval(() => {
        localStorage.setItem(
          "groupbuy_order_data",
          JSON.stringify(state.orderData)
        );
      }, 1000);
    };

    // 设置地址
    const handleSeleclAddress = () => {
      state.addressObj = JSON.parse(localStorage.getItem("selectAddress"));
      if (state.addressObj) {
        // state.orderData.address = state.addressObj.pname +
        //     state.addressObj.cityname +
        //     state.addressObj.name +
        //     state.addressObj.address;
        state.orderData.address = state.addressObj.cityname + state.addressObj.address + state.addressObj.name
        state.orderData.longitude = state.addressObj.lng;
        state.orderData.latitude = state.addressObj.lat;
        cityName = state.addressObj.cityname;
      }
    };
    // 设置是否跳舞
    const setIsDance = () => {
      getIsDance({
        latitude: state.addressObj.lat,
        longitude: state.addressObj.lng
      }).then(res => {
        state.orderData.isDance = res.data || false
        Dialog.confirm({
          message: state.orderData.isDance ? '太棒啦，该区域有熊猫跳舞服务哦！' : '主人！该地址蛋糕将由第三方配送上门，暂无法提供熊猫上门跳舞服务哦。',
          theme: 'round-button',
          showCancelButton: false,
        })
        if (!res.code === 200) {
          clearAddressSelect()
        }
      }).catch(() => {
        clearAddressSelect()
      })
    }

    // 清除地址
    const clearAddressSelect = () => {
      state.orderData.address = ''
      state.orderData.longitude = ''
      state.orderData.latitude = ''
      localStorage.removeItem('selectAddress')
    }

    const showGuide = () => {
      guideRef.value.show({channel: getChannelId()});
    };

    const goChannel = () => [
      router.push({
        path: '/channel',
        query: route.query
      })
    ]

    nextTick(() => {
      if (getChannelId()) {
        showGuide()
      }
    })

    // 页面actived时
    onActivated(() => {
      console.log('onActivated')
      handleSeleclAddress();
      if (route.query.setIsDance) {
        setIsDance();
      }
      if (route.query.clearCode) {
        clearGoodsInfo();
      }
      if (route.query.showGuide) {
        showGuide()
      }
    })

    // 初始化页面
    const init = () => {
      getCacheOrder().then(() => {
        clearGoodsInfo();
        // 下单内容修改时，进行埋点
        watch(
          () => state.orderData,
          () => {
            editTracking.send()
          },
          {deep: true}
        )
      });
      setCacheTimer();
    };
    init();

    return {
      state,
      appConfig,
      guideRef,
      formRef,
      onSelectAddress,
      beforeRead,
      onSubmit,
      onPreview,
      onSelectGoods,
      submitConfirm,
      onFailed,
      images,
      timeSelectorRef,
      onDateClick,
      onDateConfirm,
      getSpliceTimeText,
      onContact,
      goChannel,
      handleCompleteCode,
      onRecPhoneChange,
      onSamePhoneChange,
      needBeforeThreeDay,
      phoneFormatter,
    };
  },
});
</script>

<style lang="less" scoped>
@import './style/home.less';
</style>
<style>
.home-code-image-preview .van-image-preview__image {
  padding: 0 40px;
}
</style>
